{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    " # NRE named entity recognition  任务要点\n",
    "1. 已经分词的数据集 需要使用`is_split_into_words=True`\n",
    "2. -100表示不需要计算的标签 计算交叉熵损失时会忽略\n",
    "3. 多分类模型 必须指定`num_labels`\n",
    "4. 评估函数需要将预测结果转换为标签\n"
   ],
   "id": "b3217e1ff46110e3"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "1 导入包",
   "id": "851eee714f56c721"
  },
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:51.984219Z",
     "start_time": "2025-05-21T11:34:51.981078Z"
    }
   },
   "source": [
    "from transformers import AutoTokenizer, AutoModelForTokenClassification, Trainer, TrainingArguments, DataCollatorForTokenClassification\n",
    "from datasets import load_dataset\n",
    "from MyHelper import *\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ],
   "outputs": [],
   "execution_count": 11
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "2 加载数据集",
   "id": "63372a3db0a59dd4"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:54.793870Z",
     "start_time": "2025-05-21T11:34:52.007087Z"
    }
   },
   "cell_type": "code",
   "source": [
    "ds = load_dataset(\"peoples_daily_ner\", trust_remote_code=True)\n",
    "ds"
   ],
   "id": "17722ec165bfd70b",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatasetDict({\n",
       "    train: Dataset({\n",
       "        features: ['id', 'tokens', 'ner_tags'],\n",
       "        num_rows: 20865\n",
       "    })\n",
       "    validation: Dataset({\n",
       "        features: ['id', 'tokens', 'ner_tags'],\n",
       "        num_rows: 2319\n",
       "    })\n",
       "    test: Dataset({\n",
       "        features: ['id', 'tokens', 'ner_tags'],\n",
       "        num_rows: 4637\n",
       "    })\n",
       "})"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 12
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:54.800008Z",
     "start_time": "2025-05-21T11:34:54.797007Z"
    }
   },
   "cell_type": "code",
   "source": "ds[\"train\"].features",
   "id": "6435ab9420a72388",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'id': Value(dtype='string', id=None),\n",
       " 'tokens': Sequence(feature=Value(dtype='string', id=None), length=-1, id=None),\n",
       " 'ner_tags': Sequence(feature=ClassLabel(names=['O', 'B-PER', 'I-PER', 'B-ORG', 'I-ORG', 'B-LOC', 'I-LOC'], id=None), length=-1, id=None)}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 13
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:54.816175Z",
     "start_time": "2025-05-21T11:34:54.812748Z"
    }
   },
   "cell_type": "code",
   "source": [
    "label_list = ds[\"train\"].features[\"ner_tags\"].feature.names\n",
    "label_list"
   ],
   "id": "d1188d78a54a96c5",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['O', 'B-PER', 'I-PER', 'B-ORG', 'I-ORG', 'B-LOC', 'I-LOC']"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 14
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "3 数据集预处理",
   "id": "718eea5ebdd4b2f2"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "一个单词可能分词为多个， 需要重新整理标签",
   "id": "18275da7267f9f98"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:54.829507Z",
     "start_time": "2025-05-21T11:34:54.826602Z"
    }
   },
   "cell_type": "code",
   "source": "print(ds[\"train\"][0])",
   "id": "be26de7e2a2db4fb",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'id': '0', 'tokens': ['海', '钓', '比', '赛', '地', '点', '在', '厦', '门', '与', '金', '门', '之', '间', '的', '海', '域', '。'], 'ner_tags': [0, 0, 0, 0, 0, 0, 0, 5, 6, 0, 5, 6, 0, 0, 0, 0, 0, 0]}\n"
     ]
    }
   ],
   "execution_count": 15
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:55.458062Z",
     "start_time": "2025-05-21T11:34:54.843990Z"
    }
   },
   "cell_type": "code",
   "source": "tokenizer = AutoTokenizer.from_pretrained(Config.hfl_chinese_macbert_base)",
   "id": "db4ec7219a0582df",
   "outputs": [],
   "execution_count": 16
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:55.468644Z",
     "start_time": "2025-05-21T11:34:55.464571Z"
    }
   },
   "cell_type": "code",
   "source": [
    "sample = tokenizer(ds[\"train\"][0][\"tokens\"], truncation=True, max_length=128, is_split_into_words=True, return_offsets_mapping=True)\n",
    "sample"
   ],
   "id": "bb00647538cbcfe5",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'input_ids': [101, 3862, 7157, 3683, 6612, 1765, 4157, 1762, 1336, 7305, 680, 7032, 7305, 722, 7313, 4638, 3862, 1818, 511, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'offset_mapping': [(0, 0), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 0)]}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 17
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:55.481174Z",
     "start_time": "2025-05-21T11:34:55.477838Z"
    }
   },
   "cell_type": "code",
   "source": "sample.sequence_ids()",
   "id": "e66e07f4751e109d",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[None, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, None]"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 18
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:55.495056Z",
     "start_time": "2025-05-21T11:34:55.491753Z"
    }
   },
   "cell_type": "code",
   "source": "sample.word_ids()",
   "id": "dce7ec329ec89d28",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[None, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, None]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 19
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:55.609549Z",
     "start_time": "2025-05-21T11:34:55.509383Z"
    }
   },
   "cell_type": "code",
   "source": [
    "def process_function(examples, tokenizer=tokenizer):\n",
    "    tokenized_examples = tokenizer(examples[\"tokens\"], truncation=True, max_length=128, is_split_into_words=True)\n",
    "    # 处理标签\n",
    "    labels = []\n",
    "    for i, label in enumerate(examples[\"ner_tags\"]):\n",
    "        word_ids = tokenized_examples.word_ids(i)\n",
    "        label_ids = [-100 if word_id is None else label[word_id] for word_id in word_ids]\n",
    "        labels.append(label_ids)\n",
    "\n",
    "    tokenized_examples[\"labels\"] = labels\n",
    "    return tokenized_examples\n",
    "tokenized_datasets = ds.map(process_function, batched=True, num_proc=16)\n",
    "tokenized_datasets"
   ],
   "id": "6c9a3325bf86fc63",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DatasetDict({\n",
       "    train: Dataset({\n",
       "        features: ['id', 'tokens', 'ner_tags', 'input_ids', 'token_type_ids', 'attention_mask', 'labels'],\n",
       "        num_rows: 20865\n",
       "    })\n",
       "    validation: Dataset({\n",
       "        features: ['id', 'tokens', 'ner_tags', 'input_ids', 'token_type_ids', 'attention_mask', 'labels'],\n",
       "        num_rows: 2319\n",
       "    })\n",
       "    test: Dataset({\n",
       "        features: ['id', 'tokens', 'ner_tags', 'input_ids', 'token_type_ids', 'attention_mask', 'labels'],\n",
       "        num_rows: 4637\n",
       "    })\n",
       "})"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 20
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:55.614429Z",
     "start_time": "2025-05-21T11:34:55.611556Z"
    }
   },
   "cell_type": "code",
   "source": "print(tokenized_datasets[\"train\"][0])",
   "id": "56dad739ec452613",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'id': '0', 'tokens': ['海', '钓', '比', '赛', '地', '点', '在', '厦', '门', '与', '金', '门', '之', '间', '的', '海', '域', '。'], 'ner_tags': [0, 0, 0, 0, 0, 0, 0, 5, 6, 0, 5, 6, 0, 0, 0, 0, 0, 0], 'input_ids': [101, 3862, 7157, 3683, 6612, 1765, 4157, 1762, 1336, 7305, 680, 7032, 7305, 722, 7313, 4638, 3862, 1818, 511, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'labels': [-100, 0, 0, 0, 0, 0, 0, 0, 5, 6, 0, 5, 6, 0, 0, 0, 0, 0, 0, -100]}\n"
     ]
    }
   ],
   "execution_count": 21
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "创建模型",
   "id": "507cdf94d50628ff"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:56.665753Z",
     "start_time": "2025-05-21T11:34:55.656651Z"
    }
   },
   "cell_type": "code",
   "source": [
    "model = AutoModelForTokenClassification.from_pretrained(Config.hfl_chinese_macbert_base, num_labels=len(label_list))\n",
    "model.config.num_labels"
   ],
   "id": "a65431609c17a2b1",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Some weights of BertForTokenClassification were not initialized from the model checkpoint at hfl/chinese-macbert-base and are newly initialized: ['classifier.bias', 'classifier.weight']\n",
      "You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "7"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 22
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "创建评估函数",
   "id": "26b0b25689a6f8c2"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:34:58.740442Z",
     "start_time": "2025-05-21T11:34:56.667758Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import evaluate\n",
    "seqeval = evaluate.load(\"seqeval\")\n",
    "\n",
    "def eval_metric(pred):\n",
    "    predictions, labels = pred\n",
    "    predictions = predictions.argmax(-1)\n",
    "    true_predictions = [\n",
    "        [label_list[p] for p, l in zip(prediction, label) if l != -100] for prediction, label in zip(predictions, labels)\n",
    "    ]\n",
    "\n",
    "    true_labels = [\n",
    "        [label_list[l] for p, l in zip(prediction, label) if l != -100] for prediction, label in zip(predictions, labels)\n",
    "    ]\n",
    "\n",
    "    results = seqeval.compute(predictions=true_predictions, references=true_labels, mode=\"strict\", scheme=\"IOB2\")\n",
    "    return {\n",
    "        \"f1\": results[\"overall_f1\"]\n",
    "    }"
   ],
   "id": "907aa3085942262c",
   "outputs": [],
   "execution_count": 23
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:37:47.488918Z",
     "start_time": "2025-05-21T11:34:58.751125Z"
    }
   },
   "cell_type": "code",
   "source": [
    "args = TrainingArguments(\n",
    "    output_dir=\"./output\",\n",
    "    per_device_train_batch_size=32,\n",
    "    per_device_eval_batch_size=64,\n",
    "    # max_steps=50,\n",
    "    num_train_epochs=1,\n",
    "    eval_strategy=\"steps\",\n",
    "    logging_steps=50,\n",
    "    eval_steps=200,\n",
    "    save_total_limit=2,\n",
    "    learning_rate=5e-5,\n",
    "    weight_decay=0.01,\n",
    "    metric_for_best_model=\"f1\",\n",
    "    # load_best_model_at_end=True,\n",
    ")\n",
    "\n",
    "trainer = Trainer(\n",
    "    model=model,\n",
    "    args=args,\n",
    "    train_dataset=tokenized_datasets[\"train\"],\n",
    "    eval_dataset=tokenized_datasets[\"validation\"],\n",
    "    compute_metrics=eval_metric,\n",
    "    tokenizer=tokenizer,\n",
    "    data_collator=DataCollatorForTokenClassification(tokenizer=tokenizer),\n",
    ")\n",
    "\n",
    "trainer.train()"
   ],
   "id": "9aa11dc8ea5a4606",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ],
      "text/html": [
       "\n",
       "    <div>\n",
       "      \n",
       "      <progress value='653' max='653' style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
       "      [653/653 02:47, Epoch 1/1]\n",
       "    </div>\n",
       "    <table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       " <tr style=\"text-align: left;\">\n",
       "      <th>Step</th>\n",
       "      <th>Training Loss</th>\n",
       "      <th>Validation Loss</th>\n",
       "      <th>F1</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>200</td>\n",
       "      <td>0.038000</td>\n",
       "      <td>0.038342</td>\n",
       "      <td>0.899128</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>400</td>\n",
       "      <td>0.030600</td>\n",
       "      <td>0.021876</td>\n",
       "      <td>0.938075</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>600</td>\n",
       "      <td>0.020700</td>\n",
       "      <td>0.018520</td>\n",
       "      <td>0.947048</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table><p>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "TrainOutput(global_step=653, training_loss=0.05139922196613154, metrics={'train_runtime': 168.3369, 'train_samples_per_second': 123.948, 'train_steps_per_second': 3.879, 'total_flos': 1224388347582642.0, 'train_loss': 0.05139922196613154, 'epoch': 1.0})"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 24
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:37:53.530524Z",
     "start_time": "2025-05-21T11:37:47.510922Z"
    }
   },
   "cell_type": "code",
   "source": "trainer.evaluate(eval_dataset=tokenized_datasets[\"validation\"])",
   "id": "17a743d982fb9a48",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ],
      "text/html": [
       "\n",
       "    <div>\n",
       "      \n",
       "      <progress value='110' max='37' style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
       "      [37/37 00:16]\n",
       "    </div>\n",
       "    "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "{'eval_loss': 0.017697671428322792,\n",
       " 'eval_f1': 0.9491758241758241,\n",
       " 'eval_runtime': 6.0094,\n",
       " 'eval_samples_per_second': 385.893,\n",
       " 'eval_steps_per_second': 6.157,\n",
       " 'epoch': 1.0}"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 25
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:38:05.125264Z",
     "start_time": "2025-05-21T11:37:53.556551Z"
    }
   },
   "cell_type": "code",
   "source": "trainer.evaluate(eval_dataset=tokenized_datasets[\"test\"])",
   "id": "e1c1116c8faf9171",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'eval_loss': 0.022336069494485855,\n",
       " 'eval_f1': 0.9373829274819374,\n",
       " 'eval_runtime': 11.5627,\n",
       " 'eval_samples_per_second': 401.03,\n",
       " 'eval_steps_per_second': 6.313,\n",
       " 'epoch': 1.0}"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 26
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:38:05.149165Z",
     "start_time": "2025-05-21T11:38:05.145770Z"
    }
   },
   "cell_type": "code",
   "source": "model.config.id2label",
   "id": "5558fef63d3223b",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0: 'LABEL_0',\n",
       " 1: 'LABEL_1',\n",
       " 2: 'LABEL_2',\n",
       " 3: 'LABEL_3',\n",
       " 4: 'LABEL_4',\n",
       " 5: 'LABEL_5',\n",
       " 6: 'LABEL_6'}"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 27
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:38:05.179539Z",
     "start_time": "2025-05-21T11:38:05.176535Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from transformers import pipeline\n",
    "model.config.id2label = {i: label for i, label in enumerate(label_list)}"
   ],
   "id": "a2c4a89d2b80228f",
   "outputs": [],
   "execution_count": 28
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:38:05.216291Z",
     "start_time": "2025-05-21T11:38:05.196456Z"
    }
   },
   "cell_type": "code",
   "source": [
    "pipe = pipeline(\n",
    "    \"token-classification\",\n",
    "    model=model,\n",
    "    tokenizer=tokenizer,\n",
    "    # aggregation_strategy=\"simple\",\n",
    ")\n",
    "\n",
    "pipe(\"赵小明在北京电视台上班\")"
   ],
   "id": "8a63f5ab2600b19d",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Device set to use cuda:0\n",
      "Asking to truncate to max_length but no maximum length is provided and the model has no predefined maximum length. Default to no truncation.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[{'entity': 'B-PER',\n",
       "  'score': np.float32(0.99879885),\n",
       "  'index': 1,\n",
       "  'word': '赵',\n",
       "  'start': 0,\n",
       "  'end': 1},\n",
       " {'entity': 'I-PER',\n",
       "  'score': np.float32(0.998552),\n",
       "  'index': 2,\n",
       "  'word': '小',\n",
       "  'start': 1,\n",
       "  'end': 2},\n",
       " {'entity': 'I-PER',\n",
       "  'score': np.float32(0.9983183),\n",
       "  'index': 3,\n",
       "  'word': '明',\n",
       "  'start': 2,\n",
       "  'end': 3},\n",
       " {'entity': 'B-ORG',\n",
       "  'score': np.float32(0.9937503),\n",
       "  'index': 5,\n",
       "  'word': '北',\n",
       "  'start': 4,\n",
       "  'end': 5},\n",
       " {'entity': 'I-ORG',\n",
       "  'score': np.float32(0.99387074),\n",
       "  'index': 6,\n",
       "  'word': '京',\n",
       "  'start': 5,\n",
       "  'end': 6},\n",
       " {'entity': 'I-ORG',\n",
       "  'score': np.float32(0.99509025),\n",
       "  'index': 7,\n",
       "  'word': '电',\n",
       "  'start': 6,\n",
       "  'end': 7},\n",
       " {'entity': 'I-ORG',\n",
       "  'score': np.float32(0.9915515),\n",
       "  'index': 8,\n",
       "  'word': '视',\n",
       "  'start': 7,\n",
       "  'end': 8},\n",
       " {'entity': 'I-ORG',\n",
       "  'score': np.float32(0.99527764),\n",
       "  'index': 9,\n",
       "  'word': '台',\n",
       "  'start': 8,\n",
       "  'end': 9}]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 29
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:38:05.238152Z",
     "start_time": "2025-05-21T11:38:05.226295Z"
    }
   },
   "cell_type": "code",
   "source": [
    "pipe = pipeline(\n",
    "    \"token-classification\",\n",
    "    model=model,\n",
    "    tokenizer=tokenizer,\n",
    "    aggregation_strategy=\"simple\",\n",
    ")\n",
    "\n",
    "pipe(\"赵小明在北京电视台上班\")"
   ],
   "id": "d00bcf9c439d51f2",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Device set to use cuda:0\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[{'entity_group': 'PER',\n",
       "  'score': np.float32(0.99855644),\n",
       "  'word': '赵 小 明',\n",
       "  'start': 0,\n",
       "  'end': 3},\n",
       " {'entity_group': 'ORG',\n",
       "  'score': np.float32(0.9939081),\n",
       "  'word': '北 京 电 视 台',\n",
       "  'start': 4,\n",
       "  'end': 9}]"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 30
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-21T11:38:05.274620Z",
     "start_time": "2025-05-21T11:38:05.272419Z"
    }
   },
   "cell_type": "code",
   "source": "",
   "id": "1ad4819104ce666a",
   "outputs": [],
   "execution_count": null
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
